//通用麻将算法
//http://www.cnblogs.com/laddc/p/6646365.html
//通用麻将算法

var logger = require("../utils/log");

function checkPingHu(seat, begin, end, need258) {
    //每种类型的牌都判断是否能胡
    for(var i = begin; i <= end; ++i){
        //将牌加入到计数中
        var oldC = seat.countMap[i];
        if(oldC){
            seat.countMap[i]++;
        } else {
            seat.countMap[i] = 1;
            oldC = 0;
        }
        seat.holds.push(i);
        seat.holds.sort(function (a, b) {
            return a - b;
        });

        //逐个判定手上的牌
        // logger.info('--------checkPingHu--------', i);
        var can = checkCanHu(seat, need258);
        if(can){ //平胡 0番
            seat.tingMap[i] = 1;
            logger.info('--------tingMap--------', i);
        }

        //搞完以后，撤消刚刚加的牌
        if (oldC == 0) {
            delete seat.countMap[i];
        } else {
            seat.countMap[i] = oldC;
        }
        var index = seat.holds.indexOf(i);
        seat.holds.splice(index, 1);
    }
};

function checkCanHu(seat) {
    for(var i in seat.countMap){
        if (seat.countMap[i] < 2) continue;
        if (!isTTW(i) || !is258(i)) continue;
        //如果当前牌大于等于２，则将它选为将牌
        seat.countMap[i] -= 2;

        //逐个判定剩下的牌是否满足　３Ｎ规则,一个牌会有以下几种情况
        //1、1张，则只可能A,A+1,A+2 手牌已经排序 只匹配这种类型
        //2、2张，则可能是将牌  或者是匹配关系
        //3、3张，则可能是一坎，或者是将牌  或者是匹配关系
        //4、4张，则只可能是一坎+单张

        // logger.debug('checkCanHu', i);
        var match = beginMatch(seat);

        seat.countMap[i] += 2;

        if (match) { //没匹配上 则换将牌 再次匹配 如果匹配上 直接返回
            return true;
        }
    }
    return false;
};

function checkCanHu(seat, need258) {
    for(var i in seat.countMap){
        if (seat.countMap[i] < 2) continue;
        if (need258 && (!isTTW(i) || !is258(i))) continue;
        //如果当前牌大于等于２，则将它选为将牌
        seat.countMap[i] -= 2;

        //逐个判定剩下的牌是否满足　３Ｎ规则,一个牌会有以下几种情况
        //1、1张，则只可能A,A+1,A+2 手牌已经排序 只匹配这种类型
        //2、2张，则可能是将牌  或者是匹配关系
        //3、3张，则可能是一坎，或者是将牌  或者是匹配关系
        //4、4张，则只可能是一坎+单张

        // logger.debug('checkCanHu', i);
        var match = beginMatch(seat);

        seat.countMap[i] += 2;

        if (match) { //没匹配上 则换将牌 再次匹配 如果匹配上 直接返回
            return true;
        }
    }
    return false;
};

function beginMatch(seat) {
    var selected = -1;
    var count = 0;
    var length = seat.holds.length;

    for(var i = 0; i < length; ++i){
        var pai = seat.holds[i];
        count = seat.countMap[pai];
        if(count > 0){
            selected = pai;
            break;
        }
    }
    //如果没有找到剩余牌，则表示匹配成功了
    if(selected == -1) return true;
    // logger.debug('selected', selected);
    // logger.debug('count', count);

    if(count == 3){ //直接作为一坎 先移除
        seat.countMap[selected] = 0;
        var match = beginMatch(seat);
        //立即恢复对数据的修改
        seat.countMap[selected] = 3;
        return match;
    } else if(count == 4){ //直接作为一坎 先移除
        //直接作为一坎
        seat.countMap[selected] = 1;
        var match = beginMatch(seat);
        //立即恢复对数据的修改
        seat.countMap[selected] = 4;
        //如果作为一坎能够把牌匹配完，直接返回TRUE。
        return match;
    } else { //按单牌处理
        return matchSingle(seat, selected);
    }
};

function matchSingle(seat, selected) {
    //分开匹配 A-2,A-1,A
    var matched = true;
    var value = selected % 10;
    if (value > 7) { //如果是东南西中发财 则；另外考虑
        matched = false;
    } else {
        for(var i = 1; i < 3; ++i){
            var pai = selected + i;
            var count = seat.countMap[pai];
            // logger.debug('matchSingle pai', pai);
            // logger.debug('matchSingle count', count);
            if(count == 0 || count == null){
                matched = false;
                break;
            }
        }
        if (matched) {
            seat.countMap[selected + 2] --;
            seat.countMap[selected + 1] --;
            seat.countMap[selected] --;
            var result = beginMatch(seat);
            seat.countMap[selected + 2] ++;
            seat.countMap[selected + 1] ++;
            seat.countMap[selected] ++;
            return result;
        }
    }
    return false;
};

//筒条万
function isTTW(pai) {
    return pai > 0 && pai < 30;
};

//258
function is258(pai) {
    var num = pai%10;
    return num == 2 || num == 5 || num ==8;
};

exports.checkPingHu = checkPingHu;

